/*-------------------------------------------------------------------------
 *
 * shm_toc.h
 *	  共享内存段目录
 *
 * 此文件旨在提供一种简单的方法，将一块共享内存（可能是通过 dsm_create 动态分配的共享内存）划分成多个区域，并跟踪这些区域的地址或这些区域内关键数据结构的地址。
 * 此功能不适合大量密钥，并且如果这样使用性能较差；如果需要大量指针，请将它们存储在段内的其他数据结构中，并只在目录中放置指向数据结构本身的指针。
 *
 * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/include/storage/shm_toc.h
 *
 *-------------------------------------------------------------------------
 */
#ifndef SHM_TOC_H
#define SHM_TOC_H

#include "storage/shmem.h"		/* 用于 add_size() */

/* shm_toc 是一种仅在 shm_toc.c 内部已知的不透明类型 */
typedef struct shm_toc shm_toc;

extern shm_toc *shm_toc_create(uint64 magic, void *address, Size nbytes);
extern shm_toc *shm_toc_attach(uint64 magic, void *address);
extern void *shm_toc_allocate(shm_toc *toc, Size nbytes);
extern Size shm_toc_freespace(shm_toc *toc);
extern void shm_toc_insert(shm_toc *toc, uint64 key, void *address);
extern void *shm_toc_lookup(shm_toc *toc, uint64 key, bool noError);

/*
 * 用于估算存储 TOC 及其依赖对象所需的大块共享内存的工具。注意：我们并不真正支持大量键，但声明 number_of_keys 为 Size 仍然很方便。
 */
typedef struct
{
	Size		space_for_chunks;
	Size		number_of_keys;
} shm_toc_estimator;

#define shm_toc_initialize_estimator(e) \
	((e)->space_for_chunks = 0, (e)->number_of_keys = 0)
#define shm_toc_estimate_chunk(e, sz) \
	((e)->space_for_chunks = add_size((e)->space_for_chunks, BUFFERALIGN(sz)))
#define shm_toc_estimate_keys(e, cnt) \
	((e)->number_of_keys = add_size((e)->number_of_keys, cnt))

extern Size shm_toc_estimate(shm_toc_estimator *e);

#endif							/* SHM_TOC_H */
